package com.eternal.login.controller;

import com.eternal.Exception.ResultVo;

import com.eternal.login.shiro.ShiroCryptographyUtil;
import com.eternal.permission.entity.PermissionInfo;
import com.eternal.permission.entity.enums.PTypeEnum;
import com.eternal.util.user.entity.UserInfo;
import com.eternal.util.user.service.UserUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.subject.support.DefaultSubjectContext;
import org.apache.shiro.util.ThreadContext;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import sun.security.provider.SHA;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.*;

@RestController
public class LoginController {
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    private Cache<String, Deque<Serializable>> cache;

    @PostMapping("/login")
   // @RequiresPermissions("login")
    public ResultVo login(UserInfo userInfo) {
        UsernamePasswordToken token = new UsernamePasswordToken(userInfo.getUserId(), ShiroCryptographyUtil.encryptMD5(userInfo.getPassword(), userInfo.getUserId(), 1), true);

        Subject subject = SecurityUtils.getSubject();
        subject.login(token);

        return new ResultVo(subject.getPrincipal());
    }

    @GetMapping("/logOut")
    @RequiresPermissions("logOut")
    public ResultVo logOut(String userId) {
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return new ResultVo();
    }

    @PostMapping("/weChatLogin")
   // @RequiresPermissions("weChatLogin")
    public ResultVo weChatLogin(String userId, String password, String openId) {
        UsernamePasswordToken token = new UsernamePasswordToken(userId, ShiroCryptographyUtil.encryptMD5(password, userId, 1), true);

        Subject subject = SecurityUtils.getSubject();
        subject.login(token);

        UserInfo userInfo = new UserInfo(userId);
        UserInfo userInfo1 = userInfo.selectById();
        userInfo1.setOpenId(openId);
        userInfo1.updateById();
        return new ResultVo(userInfo1);
    }


    @GetMapping("/queryModels")
    public ResultVo<List<PermissionInfo>> queryModels() {
        Set<PermissionInfo> permissionInfos = UserUtil.getUser().getPermissionInfos();
        List<PermissionInfo> permissionInfosList = new ArrayList<>();
        for (PermissionInfo permissionInfo : permissionInfos) {
            if (PTypeEnum.MODEL == permissionInfo.getPType()) {
                permissionInfosList.add(permissionInfo);
            }
        }
        return new ResultVo(permissionInfosList);
    }

    @GetMapping("/queryMenus")
    public ResultVo<List<Map<String, Object>>> queryMenus(String modelName) {
        Set<PermissionInfo> permissionInfos = UserUtil.getUser().getPermissionInfos();
        List<Map<String, Object>> result = new ArrayList<>();
        for (PermissionInfo permissionInfo : permissionInfos) {
            if (PTypeEnum.MENU == permissionInfo.getPType() && permissionInfo.getPCode().indexOf(modelName) != -1 && result.toString().indexOf(permissionInfo.getGroupCode()) == -1) {
                Map<String, Object> map = new HashMap();
                map.put("groupCode", permissionInfo.getGroupCode());
                map.put("groupName", permissionInfo.getGroupName());
                result.add(map);
            }
        }

        for (Map<String, Object> map : result) {
            List<PermissionInfo> permissionInfoList = new ArrayList<>();
            for (PermissionInfo permissionInfo : permissionInfos) {
                if (map.get("groupCode").toString().equals(permissionInfo.getGroupCode()) && !map.get("groupName").toString().equals(permissionInfo.getPName()))
                    permissionInfoList.add(permissionInfo);
            }
            map.put("permission", permissionInfoList);
        }

        return new ResultVo(result);
    }

}
